home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Cheat II / cheatfile.c < prev    next >
Text File  |  1995-09-03  |  8KB  |  331 lines

  1. // cheatfile.c
  2. // saves the current data and scales 'n stuff
  3.  
  4. #include <Files.h>
  5. #include <Pascal.h>
  6. #include <string.h>
  7. #include <stdio.h>
  8. #include <ctype.h>
  9. #include "main.h"
  10. #include "cheatWindow.h"
  11. #include "cheatprefs.h"
  12. #include "cheat.h"
  13. #include "cheatfile.h"
  14. #include "resrefs.h"
  15. #include "error.h"
  16.  
  17. #define cheatfilecreator 'chit'
  18. #define cheatfiletype 'TEXT'
  19.  
  20.     // externs
  21.     
  22. int wegotfile = 0;
  23.  
  24.     // globs
  25. int alreadysaved = false;
  26. short VRefNum;
  27. Str255 fname = "";
  28.  
  29. const char *sizestring[] = {
  30.     "Longint", "Integer", "Byte"
  31. };
  32.  
  33.     // when file name might have changed, we call this to change the append to button
  34. static void updateappendoldbutt(void)
  35. {
  36.     Str255 newt = "\pAppend To ";
  37.     int i;
  38.     
  39.     wegotfile = true;
  40.         // append strings
  41.     for (i=0;i<fname[0];i++) {
  42.         newt[0]++;
  43.         newt[newt[0]] = fname[i+1];
  44.     }
  45.     SetCTitle((ControlHandle) sitem[riAppendToOld], newt);        // change in shortcuts
  46.     fixshortbuttz();
  47. }
  48.  
  49.     // called when we're reading in from a file
  50. static void addCheat(shortcut *ncut)
  51. {
  52.     shortcut newcut;
  53.     Str255 s;
  54.     long l;
  55.     short id;
  56.     Cell cell, well = {0, 0};
  57.     Handle h;
  58.     
  59.     newcut = *ncut;
  60.         // try to grow our records
  61.     SetHandleSize((Handle) cut, sizeof(shortcut) * (gnumcuts + 1));
  62.     if (MemError()) {
  63.         stdmessage("\pSorry, there is not enough memory allocated to remember this cheat.");
  64.         return;
  65.     }
  66.     HLock((Handle) cut);
  67.     (*cut)[gnumcuts] = newcut;
  68.     HUnlock((Handle) cut);
  69.     
  70.         // add a cell in the list
  71.     cell.v = LAddRow(1, -1, slist);
  72.     cell.h = 0;
  73.     LSetCell((Ptr) &newcut.title[1], newcut.title[0], cell, slist);
  74.     
  75.     gnumcuts++;
  76.     
  77.         // add the resource to our file
  78.     h = NewHandle(sizeof(shortcut));
  79.     verify(h);
  80.     HLock(h);
  81.     **((shortcut **) h) = newcut;
  82.     HUnlock(h);
  83.     id = Unique1ID(kcheatsheettype);
  84.     AddResource(h, kcheatsheettype, id, newcut.title);
  85.     if (ResError())
  86.         stdmessage("\pI was unable to save this cheat.");
  87.     else {
  88.         WriteResource(h);
  89.         ReleaseResource(h);
  90.     }
  91. }
  92.  
  93. #define kbufsize 700
  94.     // reads a file from disk, assumes name and vref already set
  95. static void readFile(void)
  96. {
  97.     short fref;
  98.     OSErr result;
  99.     long length;
  100.     Str255 str;
  101.     char buf[kbufsize], *c, *d, tmp[20];
  102.     int numvalid = 0;
  103.     shortcut ourcut;
  104.      short wedone = false;
  105.  
  106.     result = FSOpen(fname, VRefNum, &fref);
  107.     if (result)    { // no existing file forget it
  108.         SysBeep(1);
  109.           return;
  110.       }
  111.  
  112.           // loop through trying to read the next cheat from the file
  113.       while (1) {
  114.               // read in some of the file, enough to fill buffer (maybe)
  115.         length = kbufsize - numvalid;        // ask to fill buffer
  116.         if (length) {
  117.             result = FSRead(fref, &length, (Ptr) &buf[numvalid]);      // get info
  118.             numvalid += length;        // increase by number of bytes we read
  119.                                     // fine if less than requested
  120.         }
  121.             // advance past whitespace
  122.         c = buf;
  123.         if (isspace(*c)) while (isspace(*++c));
  124.         if (((long)c - (long)buf) >= numvalid)
  125.             break;        // we're done done done
  126.             // read in title
  127.         if (*c != 'T') {
  128.             // stdmessage("\pError in parsing: Title not found.");
  129.             break;    // probably done
  130.         }
  131.         c += 7;        // length of "Title: "
  132.         d = c;
  133.  
  134.         while (*++d != '\r') ;        // find end of string
  135.         *d = 0;                        // never see it again, no matter
  136.  
  137.         strcpy((char *)ourcut.title, c);
  138.         c = ++d;
  139.         if (isspace(*c)) while (isspace(*++c));
  140.         
  141.             // read in comment
  142.         if (*c != 'C') {
  143.             stdmessage("\pError in parsing: Comment not found.");
  144.             break;
  145.         }
  146.         c += 9;        // length of "Comment: "
  147.         if (*c == '\r')
  148.             ourcut.comment[0] = 0;
  149.         else {
  150.             wedone = false;
  151.             
  152.             d = c;
  153.             
  154.             while (!wedone) {
  155.                 while (*++d != '\r') ;        // find end of string
  156.                 d++;
  157.                 
  158.                 if ((long) d >= (long) buf + kbufsize) {
  159.                     stdmessage("\pError in parsing: couldn't find \"Size\"");
  160.                     result = FSClose(fref);
  161.                     return;
  162.                 }
  163.                 
  164.                 if (!strncmp("Size:", d, 5))
  165.                     wedone = true;    // we done with comment
  166.                 d--;
  167.             }
  168.             *d = 0;                        // never see it again, no matter
  169.             strcpy((char *)ourcut.comment, c);
  170.             c = ++d;
  171.         }
  172.         if (isspace(*c)) while (isspace(*++c));
  173.         
  174.             // read in other stuff
  175.         d = c;
  176.         while (*++d != '\r') ;        // find end of string
  177.         if (sscanf(c, "Size: %[^,], Offset: %ld, New value: %ld", 
  178.                     tmp, &ourcut.offset, &ourcut.newval) != 3) {
  179.             stdmessage("\pError in parsing: data ended too soon.");
  180.             break;
  181.         }
  182.         else {
  183.             ourcut.datasize = -1;
  184.             switch (tmp[0]) {
  185.                 case 'B': case 'b': ourcut.datasize = ksizebyte; break;
  186.                 case 'I': case 'i': ourcut.datasize = ksizeint; break;
  187.                 case 'L': case 'l': ourcut.datasize = ksizelong; break;
  188.                 default: stdmessage("\pError in parsing: illegal size type."); break;
  189.             }
  190.             if (ourcut.datasize < 0)
  191.                 break;
  192.                 
  193.                 // okay, we finally have a good new shortcut
  194.             CtoPstr((char *) ourcut.title);
  195.             CtoPstr((char *) ourcut.comment);
  196.             addCheat(&ourcut);
  197.         }
  198.         
  199.             // scroll buffer down
  200.         c = d;
  201.         numvalid -= (long) c - (long) buf;
  202.         verify(numvalid >= 0);
  203.         memmove(buf, c, numvalid);
  204.     }
  205.     
  206.     result = FSClose(fref);
  207.     fref = 0;        // so we don't wipe out any disks (see THINK ref)
  208.   
  209.     alreadysaved = true;
  210. }
  211.  
  212. void OpenAppFile(void)            // open the file passed by the finder
  213. {
  214.     AppFile fd;
  215.     short message, count, i;
  216.     
  217.     CountAppFiles(&message, &count);
  218.     if (count) {
  219.         GetAppFiles(1, &fd);
  220.         for (i=0;i<64;i++)
  221.             fname[i] = fd.fName[i];
  222.         VRefNum = fd.vRefNum;
  223.         readFile();        // read in info
  224.         ClrAppFiles(1);
  225.         updateappendoldbutt();
  226.     }
  227. }
  228.  
  229.     // called if user selects Open in the File menu
  230. void doOpenFile(void)
  231. {
  232.     Point pt;
  233.     SFReply reply;
  234.     SFTypeList tlist;
  235.     int i;
  236.     
  237.         // use SF to let them select a file
  238.     SetPt(&pt, 100, 50);
  239.     tlist[0] = cheatfiletype;
  240.     SFGetFile(pt, "\pOpen file…", nil, 1, tlist, nil, &reply);
  241.     
  242.     if (reply.good) {
  243.             // get name and vrefnum from reply
  244.         for (i=0;i<64;i++)
  245.             fname[i] = reply.fName[i];
  246.         VRefNum = reply.vRefNum;
  247.         readFile();        // read in info
  248.         updateappendoldbutt();
  249.     }
  250. }
  251.  
  252.  
  253. void doSaveFile(int howsave, shortcut *cut, int count)
  254. {
  255.     long DirID, ThePrefs;
  256.     short fref;
  257.     OSErr result;
  258.     long length;
  259.     Point pt;
  260.     SFReply reply;
  261.     int i;
  262.     shortcut ourcut;
  263.     char buf[700];
  264.     
  265.     if (howsave == knewfile) {
  266.             // use SF to let them select a file
  267.         SetPt(&pt, 100, 50);
  268.         SFPutFile(pt, "\pSave cheat as…", fname, nil, &reply);
  269.         if (reply.good) {
  270.                 // get name and vrefnum from reply
  271.             for (i=0;i<64;i++)
  272.                 fname[i] = reply.fName[i];
  273.             VRefNum = reply.vRefNum;
  274.             alreadysaved = true;        // we are attached to this file now
  275.             updateappendoldbutt();
  276.         }
  277.         else
  278.             return;
  279.             // erase any existing file
  280.         result = FSDelete(fname, VRefNum);
  281.         result = Create(fname, VRefNum, cheatfilecreator, cheatfiletype);    // make it
  282.         if (result) {
  283.             stdmessage("\pError: failed to create file");
  284.             return;
  285.         }
  286.     }
  287.     else if ((howsave == kappendnew) || !alreadysaved) {
  288.         SFTypeList tlist;
  289.         
  290.             // use SF to let them select a file
  291.         SetPt(&pt, 100, 50);
  292.         tlist[0] = cheatfiletype;
  293.         SFGetFile(pt, "\pAppend to…", nil, 1, tlist, nil, &reply);
  294.         
  295.         if (reply.good) {
  296.                 // get name and vrefnum from reply
  297.             for (i=0;i<64;i++)
  298.                 fname[i] = reply.fName[i];
  299.             VRefNum = reply.vRefNum;
  300.             alreadysaved = true;
  301.             updateappendoldbutt();
  302.         }
  303.         else
  304.             return;
  305.     }
  306.     else {        // append to old one
  307.     
  308.     }
  309.     
  310.     result = FSOpen(fname, VRefNum, &fref);        // still have to open it
  311.     if (result) {    // no existing file forget it
  312.         stdmessage("\pError: failed to open file");
  313.         return;
  314.     }
  315.     result = SetFPos(fref, fsFromLEOF, 0); verify(!result);        // so we append . . .
  316.      
  317.      while (count--) {
  318.          ourcut = *cut;
  319.          PtoCstr(ourcut.title);
  320.          PtoCstr(ourcut.comment);
  321.         length = sprintf(buf, "Title: %s\15Comment: %s\15Size: %s, Offset: %ld, New value: %ld\15\15",
  322.             ourcut.title, ourcut.comment, sizestring[ourcut.datasize], ourcut.offset, ourcut.newval);
  323.         result = FSWrite(fref, &length, (Ptr) buf);      // put info
  324.         cut++;
  325.     }
  326.     
  327.     result = FSClose(fref);
  328.     result = FlushVol(0, 0);
  329.     if (result) Debugger();
  330.     fref = 0;        // so we don't wipe out any disks (see THINK ref)
  331. }